package cn.kgc.config;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.retry.RetryNTimes;
import org.apache.curator.retry.RetryOneTime;
import org.apache.curator.retry.RetryUntilElapsed;
import org.apache.zookeeper.CreateMode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author YC
 */
@Configuration
public class CuratorConfig {

    /**
     * Zookeeper地址
     */
    private final String host = "192.168.8.106:2181";
//    private final String host = "localhost:2181";
    /**
     * 会话超时时间
     */
    private final int sessionTimeoutMs = 5000;
    /**
     * 连接超时时间
     */
    private final int connectionTimeoutMs = 5000;
    /**
     * 重试次数
     */
    private final int retryCount = 3;
    /**
     * 重试间隔时间
     */
    private final int retryIntervalMs = 1000;

    /**
     * 创建CuratorFramework实例
     */
    @Bean
    public CuratorFramework curatorFramework() {
        // CuratorFramework的重试策略：
        // RetryOneTime：只重试1次
        RetryPolicy retryPolicy1 = new RetryOneTime(3000);
        // RetryNTimes：T时间内重试N次
        RetryPolicy retryPolicy2 = new RetryNTimes(3, 3000);
        // RetryUntilElapsed：在T时间内，每隔T时间重试
        RetryPolicy retryPolicy3 = new RetryUntilElapsed(10000, 3000);
        // ExponentialBackoffRetry：每隔T时间重试，重试次数N次，间隔时间不断增加（指数型重试策略）
        RetryPolicy retryPolicy4 = new ExponentialBackoffRetry(3, 3000);

        CuratorFramework curatorFramework = CuratorFrameworkFactory.builder()
                .namespace("curator")
                .connectString(host)
                .sessionTimeoutMs(sessionTimeoutMs)
                .connectionTimeoutMs(connectionTimeoutMs)
                .retryPolicy(retryPolicy4).build();
        // 启动客户端
        curatorFramework.start();
        // 命名空间不会自动创建，需要手动创建一个子节点
        try {
            // 检查节点是否存在，如果不存在则创建
            if (curatorFramework.checkExists().forPath("/abc") == null) {
                // 创建持久节点，如果父节点不存在则自动创建
                curatorFramework.create()
                        .creatingParentsIfNeeded()
                        .withMode(CreateMode.PERSISTENT)
                        .forPath("/abc", "".getBytes());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return curatorFramework;
    }

}